package com.longteng.diamond.filter;


import com.google.common.collect.Lists;
import com.longteng.diamond.service.InterfaceMockService;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by Administrator
 * DATE : 2018/8/5
 * TIME : 13:42
 * PROJECT : java-lesson
 * PACKAGE : com.longteng.lesson
 *
 * @author <a href="mailto:taki@qq.com">Administrator</a>
 */
@Component
@ConfigurationProperties(prefix = "spring.urlFilter")
public class UrlFilter implements Filter {
    @Autowired
    InterfaceMockService interfaceMockService;
    @Autowired
    ApplicationContext application;
    /**通过配置文件配置过滤掉的css js 等文件**/
    @Setter
    @Getter
    List<String> exclusions = Lists.newArrayList();

    public static final String resolvePath="/resolveMockController/resolveMockData";
    /**
     * 初始化系统自身的mappingURL，避免这些请求的url也做是否mock的查询,减少数据库操作
     * @param
     * @return
     */
    private void initRequestMapping() {
        AbstractHandlerMethodMapping<RequestMappingInfo> objHandlerMethodMapping =
                (AbstractHandlerMethodMapping<RequestMappingInfo>) application.getBean("requestMappingHandlerMapping");
        Map<RequestMappingInfo, HandlerMethod> mapRet = objHandlerMethodMapping.getHandlerMethods();
        for (RequestMappingInfo requestMappingInfo : mapRet.keySet()) {
            Set set = requestMappingInfo.getPatternsCondition().getPatterns();
            Iterator iterator = set.iterator();
            while (iterator.hasNext()) {
                exclusions.add(iterator.next().toString());
            }
        }
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        initRequestMapping();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        if (isMockCheck(httpRequest.getRequestURI())) {
            /**系统自身的url需要做mock校验吗？**/
            if (null != interfaceMockService.isMock(httpRequest)) {
                /**如果匹配上url的时候,那么去解析mock数据**/
                request.getRequestDispatcher(resolvePath).forward(request,response);
            } else {
                /**因为修改host是针对域名生效的
                 * 那么所有的接口都会调用mock服务器，如果其中的某些接口不用Mock呢？
                 * 这里面是不是可以转发一下呢？
                 * 用到httpclient转发请求了
                 * 另外一个应用场景:mock接口增加了一个开关呢?
                 * **/
                chain.doFilter(request, response);
            }
        } else {
            chain.doFilter(request, response);
        }
    }
    /**
     * 判断该url是否需要做mock检查
     * @param url
     * @return
     */
    private boolean isMockCheck(String url) {
        for (String s : exclusions) {
            if (url.endsWith(s)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void destroy() {

    }
}
